```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tomcat中JNDI资源的配置和管理</title>
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            color: #333;
            line-height: 1.6;
        }
        h1, h2, h3, h4 {
            font-family: 'Noto Serif SC', serif;
            font-weight: 600;
            margin-top: 1.5em;
            margin-bottom: 0.8em;
        }
        h1 {
            font-size: 2.2em;
            border-bottom: 2px solid #e2e8f0;
            padding-bottom: 0.3em;
        }
        h2 {
            font-size: 1.8em;
            color: #2d3748;
        }
        h3 {
            font-size: 1.4em;
            color: #4a5568;
        }
        .hero {
            background: linear-gradient(135deg, #4f46e5 0%, #805ad5 100%);
            color: white;
            padding: 4rem 2rem;
            border-radius: 0.5rem;
            margin-bottom: 3rem;
            position: relative;
            overflow: hidden;
        }
        .hero::before {
            content: "";
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: url('https://cdn.nlark.com/yuque/0/2024/png/21449790/1728790840888-d87473e1-9193-4a1e-8cc3-36f4f3c0fa7f.png') center/cover no-repeat;
            opacity: 0.1;
        }
        .hero-content {
            position: relative;
            z-index: 1;
            max-width: 1200px;
            margin: 0 auto;
        }
        .card {
            background: white;
            border-radius: 0.5rem;
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
            padding: 2rem;
            margin-bottom: 2rem;
            transition: transform 0.3s ease, box-shadow 0.3s ease;
        }
        .card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
        }
        .code-block {
            background: #f8f9fa;
            border-radius: 0.375rem;
            padding: 1rem;
            font-family: 'Courier New', Courier, monospace;
            font-size: 0.9em;
            overflow-x: auto;
            margin: 1.5rem 0;
            border-left: 4px solid #4f46e5;
        }
        .img-container {
            margin: 2rem 0;
            text-align: center;
        }
        .img-container img {
            max-width: 100%;
            height: auto;
            border-radius: 0.5rem;
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
        }
        .feature-icon {
            color: #4f46e5;
            margin-right: 0.5rem;
        }
        .footer {
            background: #1a202c;
            color: #e2e8f0;
            padding: 2rem 0;
            margin-top: 4rem;
        }
        .footer a {
            color: #a0aec0;
            transition: color 0.2s ease;
        }
        .footer a:hover {
            color: #ffffff;
            text-decoration: underline;
        }
        .highlight {
            background-color: #f0f9ff;
            padding: 0.25em 0.5em;
            border-radius: 0.25em;
            color: #1e40af;
            font-weight: 500;
        }
        .note {
            background-color: #f0fdf4;
            border-left: 4px solid #10b981;
            padding: 1rem;
            margin: 1.5rem 0;
            border-radius: 0 0.375rem 0.375rem 0;
        }
        .note-title {
            font-weight: 600;
            color: #065f46;
            margin-bottom: 0.5rem;
            display: flex;
            align-items: center;
        }
        .note-title i {
            margin-right: 0.5rem;
        }
    </style>
</head>
<body class="bg-gray-50">
    <div class="container mx-auto px-4 py-8 max-w-6xl">
        <!-- Hero Section -->
        <section class="hero">
            <div class="hero-content">
                <h1 class="text-4xl font-bold mb-4">Tomcat中JNDI资源的配置和管理</h1>
                <p class="text-xl opacity-90 mb-6">如何高效地管理应用程序所需的各种资源成为了一个关键问题。无论是数据库连接、邮件会话还是自定义配置参数，JNDI（Java Naming and Directory Interface）为我们提供了一个统一的接口，来管理和查找这些命名资源。</p>
                <div class="flex items-center">
                    <i class="fas fa-info-circle text-2xl mr-2"></i>
                    <p class="text-lg">在Tomcat中，JNDI的使用更加灵活和强大，能够帮助开发者简化资源管理，实现应用程序与底层资源的解耦。</p>
                </div>
            </div>
        </section>

        <!-- Introduction Card -->
        <div class="card">
            <p>如何在Tomcat中配置和管理JNDI资源，包括数据源的设置、连接池的管理，以及如何通过JNDI在应用中轻松访问这些资源。这不仅有助于提高应用的可维护性，还能提升其性能和扩展性。</p>
        </div>

        <!-- JNDI Overview Section -->
        <section>
            <h2>JNDI 概述</h2>
            <p>JNDI（Java Naming and Directory Interface）是Java EE规范中提供的一种API，用于实现命名和目录服务的访问。它允许Java应用程序通过统一的接口查找和检索各种命名资源，比如数据库连接池、EJB（Enterprise JavaBeans）、消息队列、配置参数等，帮助开发者管理应用程序中的资源分配和使用。</p>
            
            <div class="img-container">
                <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1728790864671-e8611222-8ed6-49e2-8bd7-9f17fa9ead79.png" alt="JNDI Overview">
            </div>

            <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                <!-- Feature 1 -->
                <div class="card">
                    <h3><i class="fas fa-link feature-icon"></i>命名服务的统一接口</h3>
                    <p>JNDI的核心功能是通过一个标准的、统一的接口来访问各种不同类型的命名服务，这意味着无论底层的命名服务使用的是LDAP、DNS、NIS，还是文件系统等，JNDI都能够提供一致的访问方式。这极大地提升了应用的可扩展性和移植性，开发者不需要关心底层实现，只需使用JNDI API来获取资源。</p>
                </div>

                <!-- Feature 2 -->
                <div class="card">
                    <h3><i class="fas fa-sitemap feature-icon"></i>资源的集中管理</h3>
                    <p>在大型分布式系统中，应用程序往往需要连接多个数据库、消息中间件或远程服务。JNDI通过将这些资源集中管理，使得应用的配置更加灵活。在Tomcat中，JNDI经常用于管理数据源（DataSource），应用程序通过JNDI查找数据源以获取数据库连接，而无需在代码中直接硬编码数据库连接信息。</p>
                </div>

                <!-- Feature 3 -->
                <div class="card">
                    <h3><i class="fas fa-project-diagram feature-icon"></i>解耦应用与底层资源</h3>
                    <p>JNDI使应用程序与底层资源之间的依赖得到解耦。开发者可以通过JNDI来抽象底层的资源配置，不论是数据库、消息服务还是文件系统，应用程序只需要通过JNDI来获取资源的引用，而不需要直接关心资源的具体实现或配置细节。</p>
                </div>

                <!-- Feature 4 -->
                <div class="card">
                    <h3><i class="fas fa-expand-arrows-alt feature-icon"></i>扩展与集成</h3>
                    <p>JNDI不仅仅局限于简单的命名查找，它还支持分布式系统中的命名和目录服务。通过JNDI，开发者可以轻松地与远程目录服务（如LDAP）进行集成，获取动态的配置信息、用户认证数据等。</p>
                </div>
            </div>
        </section>

        <!-- JNDI Configuration Scenarios -->
        <section>
            <h2>JNDI 资源的配置场景</h2>
            <p>在企业级应用中，JNDI（Java Naming and Directory Interface）资源配置的场景非常广泛，尤其是在Tomcat等应用服务器中。JNDI主要用于管理和访问诸如数据库连接池、邮件服务器、环境变量等资源。</p>
            
            <div class="img-container">
                <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1728790916261-7b457210-ee5d-4ab2-89ce-9ec38b079484.png" alt="JNDI Configuration Scenarios">
            </div>

            <div class="card">
                <h3><i class="fas fa-database feature-icon"></i>1. 数据库连接池配置</h3>
                <p>这是最常见的JNDI使用场景之一。在企业级应用中，应用程序通常需要频繁访问数据库，直接创建和销毁数据库连接会带来性能问题。为了解决这个问题，数据库连接池（DataSource）被引入，并通过JNDI进行配置和管理。</p>
                
                <div class="note">
                    <div class="note-title">
                        <i class="fas fa-lightbulb"></i>
                        <span>示例场景</span>
                    </div>
                    <p>在开发环境和生产环境中，数据库服务器地址、端口、用户和密码可能不同。通过在Tomcat中配置JNDI数据源，应用程序可以使用相同的逻辑名称访问数据库，而不用关心底层数据库的具体配置信息。</p>
                </div>

                <div class="code-block">
                    &lt;Context&gt;<br>
                    &nbsp;&nbsp;&lt;Resource name="jdbc/myDataSource" <br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;auth="Container" <br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type="javax.sql.DataSource"<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxActive="100" <br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxIdle="30" <br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxWait="10000"<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;username="dbUser" <br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;password="dbPass"<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;driverClassName="com.mysql.jdbc.Driver"<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;url="jdbc:mysql://localhost:3306/mydb"/&gt;<br>
                    &lt;/Context&gt;
                </div>
            </div>

            <div class="card">
                <h3><i class="fas fa-envelope feature-icon"></i>2. 邮件服务器配置</h3>
                <p>在企业应用中，邮件发送是一个常见功能，如用户注册时的确认邮件、系统异常时的告警邮件等。通过JNDI配置邮件服务（JavaMail Session），应用程序能够发送邮件，而不用在代码中硬编码邮件服务器的地址和认证信息。</p>
                
                <div class="code-block">
                    &lt;Resource name="mail/MyMailSession" <br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;auth="Container" <br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type="javax.mail.Session"<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mail.smtp.host="smtp.example.com" <br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mail.smtp.port="587"<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mail.smtp.auth="true"<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mail.smtp.user="user@example.com" <br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mail.smtp.password="secret"/&gt;
                </div>
            </div>

            <div class="card">
                <h3><i class="fas fa-users-cog feature-icon"></i>3. LDAP 服务器配置</h3>
                <p>LDAP（轻量级目录访问协议）常用于企业中的用户认证、权限管理等场景。通过JNDI配置LDAP服务器，应用程序可以轻松集成用户认证、权限查询等功能，而无需硬编码LDAP服务器的连接信息。</p>
                
                <div class="code-block">
                    &lt;Resource name="ldap/LDAPConnection" <br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;auth="Container" <br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type="javax.naming.directory.DirContext"<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;factory="com.sun.jndi.ldap.LdapCtxFactory"<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;url="ldap://ldap.example.com:389"<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user="cn=admin,dc=example,dc=com"<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;password="password"/&gt;
                </div>
            </div>
        </section>

        <!-- Configuration Steps -->
        <section>
            <h2>配置步骤</h2>
            <p>在Tomcat中实现JNDI资源的配置和管理，涉及多个步骤和细节。为了确保JNDI资源能够正确地在应用程序中使用，必须按照以下配置流程进行操作。</p>

            <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                <!-- Step 1 -->
                <div class="card">
                    <h3>1. 确认Tomcat环境的准备</h3>
                    <p>确保Tomcat服务器已正确安装并运行。Tomcat作为支持JNDI的容器，需要相应的配置来确保应用程序能够查找到所需的资源。</p>
                    <ul class="list-disc pl-5 mt-2">
                        <li>Tomcat正确安装并配置</li>
                        <li>Java环境（JDK）已配置完毕</li>
                        <li>Tomcat的配置文件能够编辑和调整</li>
                    </ul>
                </div>

                <!-- Step 2 -->
                <div class="card">
                    <h3>2. 在Tomcat中定义JNDI资源</h3>
                    <p>JNDI资源的配置通常位于<code class="highlight">conf/context.xml</code>、<code class="highlight">conf/server.xml</code>或者每个应用的<code class="highlight">META-INF/context.xml</code>文件中。</p>
                </div>

                <!-- Step 3 -->
                <div class="card">
                    <h3>3. 配置web.xml中对JNDI资源的引用</h3>
                    <p>在应用程序的<code class="highlight">WEB-INF/web.xml</code>文件中，需要声明对JNDI资源的引用。</p>
                </div>

                <!-- Step 4 -->
                <div class="card">
                    <h3>4. 在应用代码中查找和使用JNDI资源</h3>
                    <p>一旦资源在Tomcat中配置好并在<code class="highlight">web.xml</code>中声明，下一步就是在Java代码中使用JNDI API来查找和使用这些资源。</p>
                </div>
            </div>

            <div class="note mt-6">
                <div class="note-title">
                    <i class="fas fa-code"></i>
                    <span>代码示例：JNDI资源查找</span>
                </div>
                <div class="code-block">
                    InitialContext ctx = new InitialContext();<br>
                    DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/MyDataSource");<br>
                    Connection conn = ds.getConnection();
                </div>
            </div>
        </section>

        <!-- Server.xml Configuration -->
        <section>
            <h2>在server.xml中配置JNDI资源</h2>
            <p>在Tomcat的<code class="highlight">server.xml</code>中配置JNDI资源是实现外部资源管理的关键步骤之一。<code class="highlight">server.xml</code>文件位于Tomcat的<code class="highlight">conf</code>目录下，是Tomcat的全局配置文件，通常用于定义全局资源，适用于所有部署在该Tomcat实例上的应用程序。</p>

            <div class="card">
                <h3>基本配置结构</h3>
                <p><code class="highlight">server.xml</code>中的JNDI资源配置通常放置在<code class="highlight">&lt;GlobalNamingResources&gt;</code>元素中，该元素专门用于定义全局资源。</p>
                
                <div class="code-block">
                    &lt;GlobalNamingResources&gt;<br>
                    &nbsp;&nbsp;&lt;Resource name="jdbc/MyGlobalDataSource" <br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;auth="Container" <br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type="javax.sql.DataSource" <br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;driverClassName="com.mysql.cj.jdbc.Driver" <br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;url="jdbc:mysql://localhost:3306/mydb"<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;username="dbUser" <br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;password="dbPassword" <br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxTotal="100" <br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxIdle="30" <br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxWaitMillis="10000"/&gt;<br>
                    &lt;/GlobalNamingResources&gt;
                </div>

                <h3 class="mt-4">应用程序引用全局资源</h3>
                <p>定义在<code class="highlight">server.xml</code>中的全局资源，可以在应用的<code class="highlight">web.xml</code>中通过JNDI名称进行引用。</p>
                
                <div class="code-block">
                    &lt;resource-ref&gt;<br>
                    &nbsp;&nbsp;&lt;description&gt;Global MySQL Database Connection&lt;/description&gt;<br>
                    &nbsp;&nbsp;&lt;res-ref-name&gt;jdbc/MyGlobalDataSource&lt;/res-ref-name&gt;<br>
                    &nbsp;&nbsp;&lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;<br>
                    &nbsp;&nbsp;&lt;res-auth&gt;Container&lt;/res-auth&gt;<br>
                    &lt;/resource-ref&gt;
                </div>
            </div>
        </section>

        <!-- Context.xml Configuration -->
        <section>
            <h2>在context.xml中绑定 JNDI 资源</h2>
            <p>在Tomcat的<code class="highlight">context.xml</code>中绑定JNDI资源是一种更加细粒度的配置方式，允许为特定Web应用程序定义和管理外部资源。</p>

            <div class="card">
                <h3>基本配置结构</h3>
                <p>在<code class="highlight">context.xml</code>中，JNDI资源一般通过<code class="highlight">&lt;Resource&gt;</code>标签进行定义。</p>
                
                <div class="code-block">
                    &lt;Context&gt;<br>
                    &nbsp;&nbsp;&lt;Resource name="jdbc/MyAppDataSource"<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;auth="Container"<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type="javax.sql.DataSource"<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;driverClassName="com.mysql.cj.jdbc.Driver"<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;url="jdbc:mysql://localhost:3306/mydb"<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;username="dbUser"<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;password="dbPassword"<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxTotal="100"<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxIdle="30"<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxWaitMillis="10000"/&gt;<br>
                    &lt;/Context&gt;
                </div>
            </div>
        </section>

        <!-- Web.xml Reference -->
        <section>
            <h2>在web.xml中引用JNDI资源</h2>
            <p>在<code class="highlight">web.xml</code>中引用JNDI资源是Java EE应用程序与外部资源进行交互的关键步骤。</p>

            <div class="card">
                <h3>资源引用声明</h3>
                <p>在<code class="highlight">web.xml</code>中引用JNDI资源时，通常使用<code class="highlight">&lt;resource-ref&gt;</code>标签。</p>
                
                <div class="code-block">
                    &lt;resource-ref&gt;<br>
                    &nbsp;&nbsp;&lt;description&gt;Primary DataSource for the Application&lt;/description&gt;<br>
                    &nbsp;&nbsp;&lt;res-ref-name&gt;jdbc/MyAppDataSource&lt;/res-ref-name&gt;<br>
                    &nbsp;&nbsp;&lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;<br>
                    &nbsp;&nbsp;&lt;res-auth&gt;Container&lt;/res-auth&gt;<br>
                    &lt;/resource-ref&gt;
                </div>

                <h3 class="mt-4">在应用程序代码中使用JNDI资源</h3>
                <div class="code-block">
                    Context initContext = new InitialContext();<br>
                    DataSource ds = (DataSource) initContext.lookup("java:comp/env/jdbc/MyAppDataSource");<br>
                    Connection conn = ds.getConnection();<br>
                    // 使用conn进行数据库操作
                </div>
            </div>
        </section>

        <!-- Accessing JNDI Resources -->
        <section>
            <h2>访问 JNDI 资源</h2>
            <p>在Java EE和Servlet容器（如Tomcat）中，JNDI（Java Naming and Directory Interface）提供了一种标准的方式，用于在运行时从目录服务中查找和访问各种资源。</p>

            <div class="card">
                <h3>查找步骤</h3>
                <ol class="list-decimal pl-5 space-y-2">
                    <li>初始化JNDI上下文</li>
                    <li>执行JNDI查找</li>
                    <li>使用资源</li>
                </ol>
                
                <div class="code-block mt-4">
                    // 1. 初始化JNDI上下文<br>
                    Context initContext = new InitialContext();<br><br>
                    
                    // 2. 执行JNDI查找<br>
                    DataSource ds = (DataSource) initContext.lookup("java:comp/env/jdbc/MyAppDataSource");<br><br>
                    
                    // 3. 使用资源<br>
                    Connection conn = ds.getConnection();
                </div>
            </div>
        </section>

        <!-- Footer -->
        <footer class="footer">
            <div class="container mx-auto px-4 text-center">
                <div class="mb-2">
                    <span class="font-semibold">技术小馆</span>
                </div>
                <div>
                    <a href="http://www.yuque.com/jtostring" target="_blank" rel="noopener noreferrer">技术小馆地址：http://www.yuque.com/jtostring</a>
                </div>
            </div>
        </footer>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            // Initialize Mermaid
            mermaid.initialize({
                startOnLoad: true,
                theme: 'default',
                flowchart: {
                    useMaxWidth: false,
                    htmlLabels: true
                }
            });
        });
    </script>
</body>
</html>
```